<?php

namespace App\Supports\Payment\Channels\AliBatch;

use Rainsens\Dinglog\Facades\Dinglog;
use Illuminate\Validation\ValidationException;

class AlipayBatch
{
	protected $config;
	
	/**
	 * @var \AopCertClient
	 */
	protected $aliClient;
	
	public function __construct($config = [])
	{
		$this->config = $config;
		$this->initAliClient();
	}
	
	protected function initAliClient()
	{
		require_once dirname(__FILE__).'/aop/AopCertClient.php';
		require_once dirname(__FILE__).'/aop/AopCertification.php';
		
		$config = $this->config;
		
		$aop = new \AopCertClient();
		
		$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
		$aop->appId = $config['app_id'];
		$aop->signType = 'RSA2';
		$aop->postCharset = 'utf-8';
		$aop->format = 'json';
		
		$aop->rsaPrivateKey = $config['private_key'];
		$aop->alipayPublicKey = $config['ali_public_key'];
		$aop->alipayrsaPublicKey = $aop->getPublicKey($config['ali_public_key']);
		$aop->isCheckAlipayPublicCert = true;
		$aop->appCertSN = $aop->getCertSN($config['app_cert_public_key']);
		$aop->alipayRootCertSN = $aop->getRootCertSN($config['alipay_root_cert']);
		
		$this->aliClient = $aop;
	}
	
	protected function checkAccount()
	{
		require_once dirname(__FILE__).'/aop/request/AlipayFundAccountQueryRequest.php';
		$request = new \AlipayFundAccountQueryRequest();
		$request->setBizContent(json_encode([
			'alipay_user_id' => $this->config['pid'],
			'account_type' => 'ACCTRANS_ACCOUNT',
		]));
		$result = $this->aliClient->execute($request);
		$apiName = str_replace(".", "_", $request->getApiMethodName())."_response";
		$response = $result->$apiName;
		return $response;
	}
	
	public function active()
	{
		$response = $this->checkAccount();
		
		if(!empty($response->code) && $response->code == 10000) {
			return $response->available_amount;
		} else {
			Dinglog::text("{$response->code}\n{$response->msg}\n{$response->sub_code}\n{$response->sub_msg}");
			throw ValidationException::withMessages(['err' => $response->sub_msg]);
		}
	}
	
	public function frozen()
	{
		$response = $this->checkAccount();
		
		if(!empty($response->code) && $response->code == 10000) {
			return $response->freeze_amount;
		} else {
			Dinglog::text("{$response->code}\n{$response->msg}\n{$response->sub_code}\n{$response->sub_msg}");
			throw ValidationException::withMessages(['err' => $response->sub_msg]);
		}
	}
	
	public function transfer($data = [])
	{
		require_once dirname(__FILE__).'/aop/request/AlipayFundBatchUniTransferRequest.php';
		
		$request = new \AlipayFundBatchUniTransferRequest();
		$request->setBizContent(json_encode($data));
		$result = $this->aliClient->execute($request);
		$apiName = str_replace(".", "_", $request->getApiMethodName())."_response";
		$response = $result->$apiName;
		return $response;
	}
	
	public function verify()
	{
		$response = request()->all();
		$certPath = $this->config['ali_public_key'];
		$verification = $this->aliClient->rsaCheckV1($response, $certPath, 'RSA2');
		if ($verification) {
			return json_decode($response['biz_content'], true);
		}
		return [];
	}
	
	public function detail($data = [])
	{
		require_once dirname(__FILE__).'/aop/request/AlipayFundBatchDetailQueryRequest.php';
		$request = new \AlipayFundBatchDetailQueryRequest();
		$request->setBizContent(json_encode($data));
		$result = $this->aliClient->execute($request);
		$apiName = str_replace(".", "_", $request->getApiMethodName())."_response";
		$response = $result->$apiName;
		return $response;
	}
}
